/*
package com.meihuayishu.backend.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.meihuayishu.backend.dto.*;
import com.meihuayishu.backend.entity.DivinationRecord;
import com.meihuayishu.backend.entity.User;
import com.meihuayishu.backend.repository.DivinationRecordRepository;
import com.meihuayishu.backend.repository.UserRepository;
import com.meihuayishu.backend.service.DivinationRecordService;
import com.meihuayishu.backend.service.HexagramService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class DivinationRecordServiceImpl implements DivinationRecordService {
    
    private final DivinationRecordRepository recordRepository;
    private final UserRepository userRepository;
    private final HexagramService hexagramService;
    private final ObjectMapper objectMapper;
    
    @Override
    @Transactional
    public SaveDivinationRecordResponse saveDivinationRecord(String userId, SaveDivinationRecordRequest request) {
        try {
            // 生成记录ID
            String recordId = generateRecordId();
            
            // 构建占卜记录
            DivinationRecord record = DivinationRecord.builder()
                    .recordId(recordId)
                    .userId(userId)
                    .hexagramName(getHexagramNameByCode(request.getHexagramCode()))
                    .hexagramCode(request.getHexagramCode())
                    .divinationType(DivinationRecord.DivinationType.fromValue(request.getDivinationType()))
                    .question(request.getQuestion())
                    .algorithm(request.getAlgorithm())
                    .inputDataJson(convertToJson(request.getInputData()))
                    .hexagramDataJson(convertToJson(request.getHexagramData()))
                    .aiInterpretationId(request.getAiInterpretationId())
                    .tagsJson(convertToJson(request.getTags()))
                    .isPrivate(request.getIsPrivate() != null ? request.getIsPrivate() : false)
                    .experienceGained(10) // 默认获得10经验值
                    .build();
            
            // 保存记录
            recordRepository.save(record);
            
            // 更新用户经验值
            updateUserExperience(userId, 10);
            
            // 检查成就
            List<SaveDivinationRecordResponse.Achievement> achievements = checkAchievements(userId);
            
            // 获取用户新等级
            String newLevel = getUserCurrentLevel(userId);
            
            return SaveDivinationRecordResponse.builder()
                    .recordId(recordId)
                    .userId(userId)
                    .createdAt(record.getCreatedAt())
                    .experienceGained(10)
                    .newLevel(newLevel)
                    .achievements(achievements)
                    .build();
                    
        } catch (Exception e) {
            log.error("保存占卜记录失败", e);
            throw new RuntimeException("保存占卜记录失败: " + e.getMessage());
        }
    }
    
    @Override
    public DivinationHistoryResponse getDivinationHistory(String userId, Integer page, Integer size, 
                                                         String type, LocalDate startDate, LocalDate endDate, String sort) {
        try {
            // 创建分页参数
            Pageable pageable = createPageable(page, size, sort);
            
            // 执行查询
            Page<DivinationRecord> recordPage = executeQuery(userId, type, startDate, endDate, pageable);
            
            // 转换为响应格式
            List<DivinationHistoryResponse.DivinationRecord> records = recordPage.getContent().stream()
                    .map(this::convertToHistoryRecord)
                    .collect(Collectors.toList());
            
            // 构建分页信息
            DivinationHistoryResponse.PaginationInfo pagination = DivinationHistoryResponse.PaginationInfo.builder()
                    .page(recordPage.getNumber() + 1)
                    .size(recordPage.getSize())
                    .total(recordPage.getTotalElements())
                    .totalPages(recordPage.getTotalPages())
                    .hasNext(recordPage.hasNext())
                    .hasPrevious(recordPage.hasPrevious())
                    .build();
            
            // 构建统计摘要
            DivinationHistoryResponse.SummaryInfo summary = buildSummaryInfo(userId);
            
            return DivinationHistoryResponse.builder()
                    .pagination(pagination)
                    .records(records)
                    .summary(summary)
                    .build();
                    
        } catch (Exception e) {
            log.error("获取占卜历史记录失败", e);
            throw new RuntimeException("获取占卜历史记录失败: " + e.getMessage());
        }
    }
    
    @Override
    public DivinationRecordDetailResponse getDivinationRecordDetail(String userId, String recordId) {
        try {
            DivinationRecord record = recordRepository.findByUserIdAndRecordId(userId, recordId)
                    .orElseThrow(() -> new RuntimeException("记录不存在"));
            
            // 增加查看次数
            record.setViewCount(record.getViewCount() + 1);
            recordRepository.save(record);
            
            return convertToDetailResponse(record);
            
        } catch (Exception e) {
            log.error("获取占卜记录详情失败", e);
            throw new RuntimeException("获取占卜记录详情失败: " + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public FavoriteOperationResponse toggleFavorite(String userId, FavoriteRequest request) {
        try {
            DivinationRecord record = recordRepository.findByUserIdAndRecordId(userId, request.getRecordId())
                    .orElseThrow(() -> new RuntimeException("记录不存在"));
            
            boolean isFavorite;
            if ("ADD".equals(request.getAction())) {
                record.setIsFavorite(true);
                record.setFavoritedAt(LocalDateTime.now());
                isFavorite = true;
            } else if ("REMOVE".equals(request.getAction())) {
                record.setIsFavorite(false);
                record.setFavoritedAt(null);
                isFavorite = false;
            } else {
                throw new RuntimeException("无效的操作类型");
            }
            
            recordRepository.save(record);
            
            // 获取用户总收藏数
            long favoriteCount = recordRepository.countByUserIdAndIsFavoriteTrue(userId);
            
            return FavoriteOperationResponse.builder()
                    .recordId(request.getRecordId())
                    .isFavorite(isFavorite)
                    .favoriteCount((int) favoriteCount)
                    .operatedAt(LocalDateTime.now())
                    .build();
                    
        } catch (Exception e) {
            log.error("收藏操作失败", e);
            throw new RuntimeException("收藏操作失败: " + e.getMessage());
        }
    }
    
    @Override
    public FavoriteListResponse getFavoriteList(String userId, Integer page, Integer size) {
        try {
            Pageable pageable = PageRequest.of(
                    page != null ? page - 1 : 0, 
                    size != null ? Math.min(size, 50) : 20
            );
            
            Page<DivinationRecord> favoritePage = recordRepository.findByUserIdAndIsFavoriteTrueOrderByFavoritedAtDesc(userId, pageable);
            
            List<FavoriteListResponse.FavoriteRecord> records = favoritePage.getContent().stream()
                    .map(this::convertToFavoriteRecord)
                    .collect(Collectors.toList());
            
            DivinationHistoryResponse.PaginationInfo pagination = DivinationHistoryResponse.PaginationInfo.builder()
                    .page(favoritePage.getNumber() + 1)
                    .size(favoritePage.getSize())
                    .total(favoritePage.getTotalElements())
                    .totalPages(favoritePage.getTotalPages())
                    .hasNext(favoritePage.hasNext())
                    .hasPrevious(favoritePage.hasPrevious())
                    .build();
            
            return FavoriteListResponse.builder()
                    .pagination(pagination)
                    .records(records)
                    .build();
                    
        } catch (Exception e) {
            log.error("获取收藏列表失败", e);
            throw new RuntimeException("获取收藏列表失败: " + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public boolean deleteDivinationRecord(String userId, String recordId) {
        try {
            long deletedCount = recordRepository.deleteByUserIdAndRecordId(userId, recordId);
            return deletedCount > 0;
        } catch (Exception e) {
            log.error("删除占卜记录失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional
    public boolean updateRecordTags(String userId, String recordId, List<String> tags) {
        try {
            DivinationRecord record = recordRepository.findByUserIdAndRecordId(userId, recordId)
                    .orElseThrow(() -> new RuntimeException("记录不存在"));
            
            record.setTagsJson(convertToJson(tags));
            recordRepository.save(record);
            return true;
            
        } catch (Exception e) {
            log.error("更新记录标签失败", e);
            return false;
        }
    }
    
    // 私有辅助方法
    
    private String generateRecordId() {
        return "rec_" + System.currentTimeMillis() + "_" + UUID.randomUUID().toString().substring(0, 8);
    }
    
    private String getHexagramNameByCode(String hexagramCode) {
        return hexagramService.getHexagramByCode(hexagramCode)
                .map(h -> h.getName())
                .orElse("未知卦象");
    }
    
    private String convertToJson(Object obj) {
        if (obj == null) {
            return null;
        }
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("JSON序列化失败", e);
            return null;
        }
    }
    
    private <T> T convertFromJson(String json, TypeReference<T> typeRef) {
        if (json == null || json.trim().isEmpty()) {
            return null;
        }
        try {
            return objectMapper.readValue(json, typeRef);
        } catch (JsonProcessingException e) {
            log.error("JSON反序列化失败", e);
            return null;
        }
    }
    
    private Pageable createPageable(Integer page, Integer size, String sort) {
        int pageNumber = page != null ? page - 1 : 0;
        int pageSize = size != null ? Math.min(size, 50) : 20;
        
        Sort sortOrder = Sort.by(Sort.Direction.DESC, "createdAt");
        if (sort != null && !sort.isEmpty()) {
            String[] sortParts = sort.split(",");
            if (sortParts.length == 2) {
                Sort.Direction direction = "asc".equalsIgnoreCase(sortParts[1]) ? 
                        Sort.Direction.ASC : Sort.Direction.DESC;
                sortOrder = Sort.by(direction, sortParts[0]);
            }
        }
        
        return PageRequest.of(pageNumber, pageSize, sortOrder);
    }
    
    private Page<DivinationRecord> executeQuery(String userId, String type, LocalDate startDate, 
                                               LocalDate endDate, Pageable pageable) {
        
        DivinationRecord.DivinationType divinationType = null;
        if (type != null && !"ALL".equalsIgnoreCase(type)) {
            divinationType = DivinationRecord.DivinationType.fromValue(type);
        }
        
        LocalDateTime startDateTime = startDate != null ? startDate.atStartOfDay() : null;
        LocalDateTime endDateTime = endDate != null ? endDate.atTime(23, 59, 59) : null;
        
        // 根据参数选择查询方法
        if (divinationType != null && startDateTime != null && endDateTime != null) {
            return recordRepository.findByUserIdAndDivinationTypeAndCreatedAtBetweenOrderByCreatedAtDesc(
                    userId, divinationType, startDateTime, endDateTime, pageable);
        } else if (divinationType != null) {
            return recordRepository.findByUserIdAndDivinationTypeOrderByCreatedAtDesc(
                    userId, divinationType, pageable);
        } else if (startDateTime != null && endDateTime != null) {
            return recordRepository.findByUserIdAndCreatedAtBetweenOrderByCreatedAtDesc(
                    userId, startDateTime, endDateTime, pageable);
        } else {
            return recordRepository.findByUserIdOrderByCreatedAtDesc(userId, pageable);
        }
    }
    
    private DivinationHistoryResponse.DivinationRecord convertToHistoryRecord(DivinationRecord record) {
        List<String> tags = convertFromJson(record.getTagsJson(), new TypeReference<List<String>>() {});
        
        return DivinationHistoryResponse.DivinationRecord.builder()
                .recordId(record.getRecordId())
                .question(record.getQuestion())
                .hexagram(buildHexagramInfo(record.getHexagramCode(), record.getHexagramName()))
                .divinationType(record.getDivinationType().name())
                .isFavorite(record.getIsFavorite())
                .hasAiInterpretation(record.getAiInterpretation() != null)
                .tags(tags != null ? tags : new ArrayList<>())
                .feedbackRating(record.getFeedbackRating())
                .createdAt(record.getCreatedAt())
                .build();
    }
    
    private DivinationRecordDetailResponse convertToDetailResponse(DivinationRecord record) {
        Map<String, Object> inputData = convertFromJson(record.getInputDataJson(), new TypeReference<Map<String, Object>>() {});
        List<String> tags = convertFromJson(record.getTagsJson(), new TypeReference<List<String>>() {});
        
        return DivinationRecordDetailResponse.builder()
                .recordId(record.getRecordId())
                .question(record.getQuestion())
                .divinationType(record.getDivinationType().name())
                .algorithm(record.getAlgorithm())
                .inputData(inputData != null ? inputData : new HashMap<>())
                .hexagram(buildHexagramDetail(record.getHexagramCode(), record.getHexagramName()))
                .aiInterpretation(buildAiInterpretationInfo(record))
                .isFavorite(record.getIsFavorite())
                .tags(tags != null ? tags : new ArrayList<>())
                .feedbackRating(record.getFeedbackRating())
                .feedbackComment(record.getFeedbackComment())
                .shareCount(record.getShareCount())
                .viewCount(record.getViewCount())
                .createdAt(record.getCreatedAt())
                .updatedAt(record.getUpdatedAt())
                .build();
    }
    
    private FavoriteListResponse.FavoriteRecord convertToFavoriteRecord(DivinationRecord record) {
        return FavoriteListResponse.FavoriteRecord.builder()
                .recordId(record.getRecordId())
                .question(record.getQuestion())
                .hexagram(buildFavoriteHexagramInfo(record.getHexagramCode(), record.getHexagramName()))
                .createdAt(record.getCreatedAt())
                .favoritedAt(record.getFavoritedAt())
                .build();
    }
    
    private HexagramInfo buildFavoriteHexagramInfo(String hexagramCode, String hexagramName) {
        return HexagramInfo.builder()
                .code(hexagramCode)
                .name(hexagramName)
                .upperSymbol("☲") // 这里应该根据实际卦象获取
                .lowerSymbol("☰")
                .build();
    }
    
    private DivinationHistoryResponse.DivinationRecord.HexagramInfo buildHexagramInfo(String hexagramCode, String hexagramName) {
        return DivinationHistoryResponse.DivinationRecord.HexagramInfo.builder()
                .code(hexagramCode)
                .name(hexagramName)
                .upperSymbol("☲") // 这里应该根据实际卦象获取
                .lowerSymbol("☰")
                .build();
    }
    
    private DivinationRecordDetailResponse.HexagramDetail buildHexagramDetail(String hexagramCode, String hexagramName) {
        return DivinationRecordDetailResponse.HexagramDetail.builder()
                .id(1)
                .name(hexagramName)
                .code(hexagramCode)
                .upperTrigram(DivinationRecordDetailResponse.TrigramInfo.builder()
                        .name("离")
                        .symbol("☲")
                        .element("火")
                        .build())
                .lowerTrigram(DivinationRecordDetailResponse.TrigramInfo.builder()
                        .name("乾")
                        .symbol("☰")
                        .element("金")
                        .build())
                .hexagramText("卦辞内容")
                .build();
    }
    
    private DivinationRecordDetailResponse.AiInterpretationInfo buildAiInterpretationInfo(DivinationRecord record) {
        if (record.getAiInterpretation() == null) {
            return null;
        }
        
        return DivinationRecordDetailResponse.AiInterpretationInfo.builder()
                .interpretationId(record.getAiInterpretationId())
                .summary(record.getAiInterpretation())
                .confidence(0.85)
                .generatedAt(record.getCreatedAt())
                .build();
    }
    
    private DivinationHistoryResponse.SummaryInfo buildSummaryInfo(String userId) {
        // 获取统计数据
        long totalRecords = recordRepository.countByUserId(userId);
        long favoriteCount = recordRepository.countByUserIdAndIsFavoriteTrue(userId);
        Double averageRating = recordRepository.getAverageRatingByUserId(userId);
        
        // 获取类型分布
        List<Object[]> typeDistributionData = recordRepository.countByUserIdGroupByDivinationType(userId);
        Map<String, Integer> typeDistribution = typeDistributionData.stream()
                .collect(Collectors.toMap(
                        data -> ((DivinationRecord.DivinationType) data[0]).name(),
                        data -> ((Long) data[1]).intValue()
                ));
        
        return DivinationHistoryResponse.SummaryInfo.builder()
                .totalRecords(totalRecords)
                .typeDistribution(typeDistribution)
                .favoriteCount((int) favoriteCount)
                .averageRating(averageRating != null ? averageRating : 0.0)
                .build();
    }
    
    private void updateUserExperience(String userId, int experience) {
        try {
            User user = userRepository.findById(Long.valueOf(userId))
                    .orElseThrow(() -> new RuntimeException("用户不存在"));
            
            user.setExperience(user.getExperience() + experience);
            userRepository.save(user);
            
        } catch (Exception e) {
            log.error("更新用户经验值失败", e);
        }
    }
    
    private List<SaveDivinationRecordResponse.Achievement> checkAchievements(String userId) {
        List<SaveDivinationRecordResponse.Achievement> achievements = new ArrayList<>();
        
        long totalDivinations = recordRepository.countByUserId(userId);
        
        // 检查占卜次数成就
        if (totalDivinations == 10) {
            achievements.add(SaveDivinationRecordResponse.Achievement.builder()
                    .type("DIVINATION_COUNT")
                    .name("初步探索")
                    .description("完成第10次占卜")
                    .unlockedAt(LocalDateTime.now())
                    .build());
        }
        
        return achievements;
    }
    
    private String getUserCurrentLevel(String userId) {
        try {
            User user = userRepository.findById(Long.valueOf(userId))
                    .orElse(null);
            
            if (user != null) {
                int experience = user.getExperience();
                if (experience >= 2000) return "专家";
                if (experience >= 1000) return "进阶者";
                if (experience >= 500) return "初学者";
            }
            
            return "新手";
        } catch (Exception e) {
            return "新手";
        }
    }
}
*/